package com.gthncz.proxy;

import com.gthncz.proxy.impl.Furongwang;
import com.gthncz.proxy.impl.MaotaiJiu;
import com.gthncz.proxy.impl.WuliangyeJiu;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class DynamicProxyDemo {

    public static void main(String[] args){
        /**
         * <p>
         *      动态的意思是 GuitaiA 这个代理类可以动态的代理不同的接口实现类.
         * </p>
         *
         * <p>
         *     Proxy.newProxyInstance() 根据传进去的 classloader, interfaces, invocation.
         *     反射创建对象实例.
         * </p>
         */
        SellWine maotai = new MaotaiJiu();
        InvocationHandler guitaiA = new GuitaiA(maotai);
        SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(), MaotaiJiu.class.getInterfaces(), guitaiA);
        dynamicProxy.sellWine();

        SellWine wuliangye = new WuliangyeJiu();
        InvocationHandler guitaiA2 = new GuitaiA(wuliangye);
        SellWine dynamicProxy2 = (SellWine) Proxy.newProxyInstance(WuliangyeJiu.class.getClassLoader(), WuliangyeJiu.class.getInterfaces(), guitaiA2);
        dynamicProxy2.sellWine();

        SellCigarete furongwang = new Furongwang();
        InvocationHandler guitai3 = new GuitaiA(furongwang);
        SellCigarete dynamicProxy3 = (SellCigarete) Proxy.newProxyInstance(Furongwang.class.getClassLoader(), Furongwang.class.getInterfaces(), guitai3);
        dynamicProxy3.sellCigarete();

        System.out.println(MaotaiJiu.class.getClassLoader());
        System.out.println(Arrays.toString(MaotaiJiu.class.getInterfaces()));

    }

    private class ProxyFactory {
        private Object target;

        public ProxyFactory(Object target) {
            this.target = target;
        }

        public Object getProxyInstance() {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("before  invoke ...");
                            Object ret = method.invoke(target, args);
                            System.out.println("post  invoke ...");
                            return ret;
                        }
                    });
        }

    }

}
